﻿#region File Description
//-----------------------------------------------------------------------------
// CalibrateScreen.cs
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using System.Timers;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using kinect_music_shooter.GameWorld;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Nui.Vision;
#endregion

namespace kinect_music_shooter.Screens
{
    class CalibrateMenuScreen : GameScreen
    {
        #region Fields

        ContentManager content;

        SpriteFont gameFont;

        //Flags
        bool active = true;
        bool isTracked = false;

        //Tracking-Zeugs
        /*bool KinectIsConnected;
        bool lostUserFlag = true;
        

        NuiUserTracker _skeleton;
        NuiUser firstuser;*/

        Avatar avatar;
        Texture2D calibrate;
        Texture2D CameraBild;
        String[] _calibratePicture;
        int _calibratePicturePointer = 0;
        System.Timers.Timer timerPointer, timerPointer2, timerPointer3;

        Random random = new Random();

        float pauseAlpha;

        #endregion

        #region Initialization


        /// <summary>
        /// Constructor.
        /// </summary>
        public CalibrateMenuScreen()
        {
            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            /*KinectIsConnected = KinectMusicShooterGame.KinectIsConnected;
            lostUserFlag = KinectMusicShooterGame.lostUserFlag;
            _skeleton = KinectMusicShooterGame._skeleton;
            firstuser = KinectMusicShooterGame.firstuser;*/

            if (KinectMusicShooterGame._skeleton != null)
            {
                KinectMusicShooterGame._skeleton.StopUserTracking();
                //KinectMusicShooterGame._skeleton.Stop();// .UserUpdated -= new NuiUserTracker.UserUpdatedHandler(Skeleton_UserUpdated);
                //KinectMusicShooterGame._skeleton = null;
            }
            try
            {
                KinectMusicShooterGame._skeleton = new NuiUserTracker("SamplesConfig.xml");
                KinectMusicShooterGame._skeleton.UserUpdated += new NuiUserTracker.UserUpdatedHandler(Skeleton_UserUpdated);
                //KinectMusicShooterGame._skeleton.UserUpdated += new NuiUserTracker.UserUpdatedHandler(lostUserTracking);
                KinectMusicShooterGame.KinectIsConnected = true;
                //KinectMusicShooterGame._skeleton.Start();
            }
            catch (Exception)
            {
                KinectMusicShooterGame.KinectIsConnected = false;
                isTracked = true;
                active = false;
            }

            _calibratePicture = new String[] {"Spiel", "Special", "calibrate", "calibrate_abstand", "calibrate_psi"};

            timerPointer = new System.Timers.Timer(6000);
            timerPointer.Elapsed += new ElapsedEventHandler(setCalibPicture);
        }

        private void setCalibPicture(object source, ElapsedEventArgs e)
        {
            if (_calibratePicturePointer >= 4)
            {
                active = false;
                _calibratePicturePointer = 4;
            }
            else
            {
                _calibratePicturePointer++;
            }
        }

        private void setCalibPicture(int calibratePicturePointer)
        {
            _calibratePicturePointer = calibratePicturePointer;

            if (_calibratePicturePointer >= 5)
            {
                active = false;
            }
        }


        #endregion

        /// <summary>
        /// Load graphics content for the game.
        /// </summary>
        public override void LoadContent()
        {
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            gameFont = content.Load<SpriteFont>("gamefont");

            // A real game would probably have more content than this sample, so
            // it would take longer to load. We simulate that by delaying for a
            // while, giving you a chance to admire the beautiful loading screen.
            //            Thread.Sleep(1000);           
            timerPointer.Enabled = true;
            // once the load has finished, we use ResetElapsedTime to tell the game's
            // timing mechanism that we have just finished a very long frame, and that
            // it should not try to catch up.
            ScreenManager.Game.ResetElapsedTime();
        }


        /// <summary>
        /// Unload graphics content used by the game.
        /// </summary>
        public override void UnloadContent()
        {
            content.Unload();
        }

        #region Update and Draw


        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                                                       bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, false);

            // Ohne Kinect
            //isTracked = true;

            if (!active && isTracked)
            {
                _calibratePicturePointer = 0;
                timerPointer.Enabled = false;
                LoadingScreen.Load(ScreenManager, true, ControllingPlayer, new BackgroundScreen(), new MainMenuScreen());
            }
            // Gradually fade in or out depending on whether we are covered by the pause screen.
            if (coveredByOtherScreen)
                pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            else
                pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            if (IsActive)
            {

            }
        }


        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        public override void HandleInput(InputState input)
        {
            if (input == null)
                throw new ArgumentNullException("input");
        }


        /// <summary>
        /// Draws the gameplay screen.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
            Rectangle fullscreen = new Rectangle(0, 0, viewport.Width, viewport.Height);

            calibrate = content.Load<Texture2D>(_calibratePicture[_calibratePicturePointer]);

            spriteBatch.Begin();

            spriteBatch.Draw(calibrate, fullscreen, new Microsoft.Xna.Framework.Color(TransitionAlpha, TransitionAlpha, TransitionAlpha));

            if (KinectMusicShooterGame._skeleton != null && KinectMusicShooterGame._skeleton.RawImage != null)
            {
                CameraBild = RawImageToTexture(KinectMusicShooterGame._skeleton.DepthImage);
            }
            if (CameraBild != null)
            {
                spriteBatch.Draw(CameraBild, new Rectangle(viewport.Width - 320, viewport.Height - 240, 320, 240), new Microsoft.Xna.Framework.Color(TransitionAlpha, TransitionAlpha, TransitionAlpha));
            }

            spriteBatch.End();
        }
        #endregion

        #region Tracking

        void lostUserTracking(object sender, NuiUserEventArgs e)
        {
        }

        void Skeleton_UserUpdated(object sender, NuiUserEventArgs e)
        {
                NuiState n = KinectMusicShooterGame._skeleton.State;
                isTracked = true;
                KinectMusicShooterGame.KinectIsConnected = true;
                KinectMusicShooterGame.lostUserFlag = false;
            

            foreach (var user in e.Users)
            {
                KinectMusicShooterGame.firstuser = user;
                KinectMusicShooterGame.firstuser = user;
                KinectMusicShooterGame.avatar.getuser(KinectMusicShooterGame.firstuser);
            }

            if (KinectMusicShooterGame.firstuser.Torso.X <= 0 || KinectMusicShooterGame.firstuser.Torso.X >= 640 || KinectMusicShooterGame.firstuser.Torso.Y <= 0 || KinectMusicShooterGame.firstuser.Torso.Y >= 480)
            {
                KinectMusicShooterGame._skeleton.StopUserTracking();
                KinectMusicShooterGame.lostUserFlag = true;
            }

            if (KinectMusicShooterGame.firstuser.Torso.X >= 640)
            {
                KinectMusicShooterGame._skeleton.StopUserTracking();
                KinectMusicShooterGame.lostUserFlag = true;
            }

            if (KinectMusicShooterGame.firstuser.Torso.Z <= 800)
            {
                KinectMusicShooterGame._skeleton.StopUserTracking();
                KinectMusicShooterGame.lostUserFlag = true;
            }

            if (KinectMusicShooterGame.firstuser.Torso.Z >= 5000)
            {
                KinectMusicShooterGame._skeleton.StopUserTracking();
                KinectMusicShooterGame.lostUserFlag = true;
            }

            if (KinectMusicShooterGame.lostUserFlag == true)
            {
                //ScreenManager.AddScreen(new CalibrateMenuScreen());
                //LoadingScreen.Load(ScreenManager, false, ControllingPlayer, new CalibrateMenuScreen());
            }


        }

        Texture2D RawImageToTexture(ImageSource Image)
        {
            BitmapSource bitmapsource = (BitmapSource)Image;
            Texture2D texture = new Texture2D(ScreenManager.GraphicsDevice, bitmapsource.PixelWidth, bitmapsource.PixelHeight, false, SurfaceFormat.Color);
            int stride = ((bitmapsource.PixelWidth * bitmapsource.Format.BitsPerPixel + 31) & (~31)) / 8;
            byte[] bytearray = new byte[stride * bitmapsource.PixelHeight];
            bitmapsource.CopyPixels(bytearray, stride, 0);
            byte[] newbytearray = new byte[640 * 480 * 4];

            int j = 0;
            for (int i = 0; i < (640 * 480 * 3); i += 3)
            {
                newbytearray[j] = bytearray[i];
                newbytearray[j + 1] = bytearray[i + 1];
                newbytearray[j + 2] = bytearray[i + 2];
                newbytearray[j + 3] = 255;
                j += 4;
            }
            texture.SetData<byte>(newbytearray);
            return texture;
        }

        #endregion
    }
}
